﻿using Appliaction.Dto.Inv;
using Domain.Entitys.Inv;
using Domain.IRepositorys.Inv;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace EFCore.Repositorys.Inv
{

    public class Inv_TrfRepository : IInv_TrfRepository
    {
        private readonly MyDbContext myDbContext;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="myDbContext"></param>
        public Inv_TrfRepository(MyDbContext myDbContext)
        {
            this.myDbContext = myDbContext;
        }
        /// <summary>
        /// 根据单据编号查询库存调拨单id信息,来添加详细信息
        /// </summary>
        /// <param name="trf_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> inv_tfr_id(string trf_code)
        {
            var entity = await myDbContext.inv_trf
           .FirstOrDefaultAsync(e => e.Trf_code == trf_code && e.Del_flag == '0');

            if (entity == null)
            {
                throw new Exception("未找到对应的仓库记录");
            }

            return entity.Trf_id;
        }

        /// <summary>
        /// 添加库存调拨单
        /// </summary>
        /// <param name="inv_trf"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_trf_Insert(Inv_trf inv_trf)
        {
            await myDbContext.inv_trf.AddAsync(inv_trf);
            return await myDbContext.SaveChangesAsync();
        }



        /// <summary>
        /// 根据编号查询仓库调拨单
        /// </summary>
        /// <param name="trf_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<List<Inv_trf>> Inv_trf_SelectCode(string trf_code)
        {
            var query = myDbContext.inv_trf.Where(x => x.Del_flag == '0' && x.Trf_code == trf_code).ToListAsync();
            return query;
        }

        /// <summary>
        /// 查询仓库调拨单总数
        /// </summary>
        /// <param name="trf_code"></param>
        /// <param name="trf_type"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> Inv_trf_selectCount(string trf_code, string trf_type, string proName)
        {
            var query = myDbContext.inv_trf.AsQueryable();

            query = query.Where(x => x.Del_flag == '0');

            // 条件1: 入库类型筛选（如果提供了）
            if (!string.IsNullOrEmpty(trf_code))
            {
                query = query.Where(x => x.Trf_code == trf_code);
            }

            // 条件2: 关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(trf_type))
            {
                query = query.Where(x => x.Trf_type == trf_type);

            }

            if (!string.IsNullOrEmpty(proName))
            {
                var details = myDbContext.inv_trfproddtl
                    .Where(d => d.Pro_code.Contains(proName) || d.Pro_name.Contains(proName))
                    .Select(d => d.Trf_id);

                query = query.Where(t => details.Contains(t.Trf_id));
            }

            // 统计总数
            return query.CountAsync();
        }
        /// <summary>
        /// 根据编号去询仓库调拨单详情
        /// </summary>
        /// <param name="trf_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<Inv_trfproddtl>> Inv_trf_SelectDetail(string trf_code)
        {
            var query = await myDbContext.inv_trf.Where(x => x.Del_flag == '0' && x.Trf_code == trf_code).FirstOrDefaultAsync();

            if (query == null)
            {
                throw new Exception("仓库不存在");
            }

            var Inv_trfproddtl = await myDbContext.inv_trfproddtl.Where(x => x.Trf_id == query.Trf_id).ToListAsync();

            return Inv_trfproddtl;
        }

        /// <summary>
        /// 分页查询仓库调拨单
        /// </summary>
        /// <param name="trf_code"></param>
        /// <param name="trf_type"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Trf_selectDto> Inv_trf_selectFY(string trf_code, string trf_type, int currentPage, int pageSize, string proName)
        {
            // 使用 IQueryable 延迟构建查询
            IQueryable<Inv_trf> query = myDbContext.inv_trf;

            query = query.Where(x => x.Del_flag == '0');

            // 条件1: 入库类型筛选（如果提供了）
            if (!string.IsNullOrEmpty(trf_code))
            {
                query = query.Where(x => x.Trf_code == trf_code);
            }

            // 条件2: 关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(trf_type))
            {
                query = query.Where(x => x.Trf_type == trf_type);

            }

            query = query.OrderByDescending(d => d.Create_time);


            if (!string.IsNullOrEmpty(proName))
            {
                var details = myDbContext.inv_trfproddtl
                    .Where(d => d.Pro_code.Contains(proName) || d.Pro_name.Contains(proName))
                    .Select(d => d.Trf_id);

                query = query.Where(t => details.Contains(t.Trf_id));
            }

            var result = query
          .Skip((currentPage - 1) * pageSize)
          .Take(pageSize)
          .Select(main => new Trf_selectDto
          {
              Trf_id = main.Trf_id,
              Trf_type = main.Trf_type,
              Trf_code = main.Trf_code,
              Trf_startdate = main.Trf_startdate,
              Warehouse_out_code = main.Warehouse_out_code,
              Warehouse_out_name = main.Warehouse_out_name,
              Warehouse_enter_code = main.Warehouse_enter_code,
              Warehouse_enter_name = main.Warehouse_enter_name,
              trf_audit_status = main.trf_audit_status,
              Trf_applicant = main.Trf_applicant,
              trf_audit_opinion= main.trf_audit_opinion,
              Details = main.Details.Select(detail => new Trf_selectDto.TrfDetailInfo
              {
                  Trf_id = detail.Trf_id,
                  Pro_name = detail.Pro_name,
                  Pro_code = detail.Pro_code,
                  Pro_brand = detail.Pro_brand,
                  Pro_model = detail.Pro_model,
                  Unitmeas_id = detail.Unitmeas_id,
                  Inventory_numder = detail.Inventory_numder,
                  Pro_cost_price = detail.Pro_cost_price,
                  Pro_sale_price = detail.Pro_sale_price
              }).ToList()
          })
          .ToList();

            return result;
        }

        /// <summary>
        /// 添加仓库调拨单详情
        /// </summary>
        /// <param name="inv_trfproddtl"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_trf_Selecttrfproddtl(List<Inv_trfproddtl> inv_trfproddtl)
        {
            await myDbContext.inv_trfproddtl.AddRangeAsync(inv_trfproddtl);
            return await myDbContext.SaveChangesAsync();
        }


        /// <summary>
        /// 修改仓库调拨单的审核状态
        /// </summary>
        /// <param name="inv_trf"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Trf_examineUpdate(Inv_trf inv_trf)
        {
            var Trf = await myDbContext.inv_trf.Where(e => e.Trf_code == inv_trf.Trf_code).FirstOrDefaultAsync();
            if (Trf == null)
            {

                throw new Exception("未找到对应的入库单");
            }
            // 更新审核信息
            Trf.trf_audit_by = inv_trf.trf_audit_by;
            Trf.trf_audit_status = inv_trf.trf_audit_status; // 如果传的是字符串
            Trf.trf_audit_time = inv_trf.trf_audit_time;
            Trf.trf_audit_opinion = inv_trf.trf_audit_opinion;

            // 保存更改
            return await myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 删除仓库调拨单
        /// </summary>
        /// <param name="Trf_id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Trf_delete(int Trf_id)
        {
            var query = await myDbContext.inv_trf.Where(x => x.Trf_id == Trf_id).FirstOrDefaultAsync();

            if (query == null)
            {
                throw new Exception("未找到对应的仓库调拨单");
            }
            query.Del_flag = '1';

            return await myDbContext.SaveChangesAsync();
        }



        /// <summary>
        /// 仓库调拨单修改
        /// </summary>
        /// <param name="inv_Trf"></param>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> Inv_othwr_Update(Inv_trf inv_Trf, List<Inv_trfproddtl> entities)
        {
            using var transaction = await myDbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 更新主表信息
                var existingOrder = await myDbContext.inv_trf
                    .FirstOrDefaultAsync(o => o.Trf_id == inv_Trf.Trf_id);

                if (existingOrder == null)
                {
                    throw new Exception($"调拨单 {inv_Trf.Trf_code} 不存在");
                }

                // 更新允许修改的字段
                existingOrder.Trf_type = inv_Trf.Trf_type;
                existingOrder.Trf_startdate = inv_Trf.Trf_startdate;
                existingOrder.Warehouse_out_code = inv_Trf.Warehouse_out_code;
                existingOrder.Warehouse_out_name = inv_Trf.Warehouse_out_name;
                existingOrder.Warehouse_enter_code = inv_Trf.Warehouse_enter_code;
                existingOrder.Warehouse_enter_name = inv_Trf.Warehouse_enter_name;
                existingOrder.Update_by = inv_Trf.Update_by;
                existingOrder.Update_time = inv_Trf.Update_time;
              

                myDbContext.Update(existingOrder);
                await myDbContext.SaveChangesAsync();

                // 2. 获取现有明细
                var existingDetails = await myDbContext.inv_trfproddtl
                    .Where(d => d.Trf_id == inv_Trf.Trf_id)
                    .ToListAsync();

                // 3. 识别三类记录
                var toAdd = new List<Inv_trfproddtl>();
                var toUpdate = new List<Inv_trfproddtl>();
                var toDeleteIds = new List<int>();

                // 处理传入的新明细
                foreach (var newItem in entities)
                {
                    // 新增记录：ID为0或不在现有明细中
                    if (newItem.Trfproddtl_Id == 0 ||
                        !existingDetails.Any(d => d.Trfproddtl_Id == newItem.Trfproddtl_Id))
                    {
                        toAdd.Add(newItem);
                    }
                    // 更新记录：ID存在且字段有变化
                    else
                    {
                        var existingItem = existingDetails
                            .First(d => d.Trfproddtl_Id == newItem.Trfproddtl_Id);

                        if (IsTrfDetailModified(existingItem, newItem))
                        {
                            toUpdate.Add(newItem);
                        }
                    }
                }

                // 识别需要删除的记录
                toDeleteIds = existingDetails
                    .Where(d => !entities.Any(e => e.Trfproddtl_Id == d.Trfproddtl_Id))
                    .Select(d => d.Trfproddtl_Id)
                    .ToList();


                if (toDeleteIds.Any())
                {
                    var deleteItems = existingDetails
                        .Where(d => toDeleteIds.Contains(d.Trfproddtl_Id))
                        .ToList();

                    myDbContext.RemoveRange(deleteItems);
                }

                // 4.2 更新变化的明细
                foreach (var item in toUpdate)
                {
                    var existingItem = existingDetails
                        .First(d => d.Trfproddtl_Id == item.Trfproddtl_Id);

                    // 更新允许修改的字段
                    existingItem.Pro_name = item.Pro_name;
                    existingItem.Pro_code = item.Pro_code;
                    existingItem.Pro_brand = item.Pro_brand;
                    existingItem.Pro_model = item.Pro_model;
                    existingItem.Unitmeas_id = item.Unitmeas_id;
                    existingItem.Inventory_numder = item.Inventory_numder; 
                    existingItem.Pro_cost_price = item.Pro_cost_price;
                    existingItem.Pro_sale_price = item.Pro_sale_price;
                    existingItem.Pending_numder= item.Pending_numder;
                    existingItem.stock_entry_no = item.stock_entry_no;
                    myDbContext.Update(existingItem);
                }

                // 4.3 添加新明细
                foreach (var item in toAdd)
                {
                    item.Trf_id = inv_Trf.Trf_id;
                    await myDbContext.AddAsync(item);
                }

                await myDbContext.SaveChangesAsync();
                await transaction.CommitAsync();

                return 1;
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                // 记录日志
                // logger.LogError(ex, "更新调拨单失败");
                return 0;
            }
        }



        // 辅助方法：检查调拨单明细是否被修改
        private bool IsTrfDetailModified(Inv_trfproddtl existing, Inv_trfproddtl updated)
        {
            return existing.Pro_name != updated.Pro_name ||
                   existing.Pro_code != updated.Pro_code ||
                   existing.Pro_brand != updated.Pro_brand ||
                   existing.Pro_model != updated.Pro_model ||
                   existing.Unitmeas_id != updated.Unitmeas_id ||
                   existing.Inventory_numder != updated.Inventory_numder ||
                   existing.Pro_cost_price != updated.Pro_cost_price ||
                   existing.Pro_sale_price != updated.Pro_sale_price;
        }
        /// <summary>
        /// 其他入库单查询仓库调拨单
        /// </summary>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Inv_trf> Inv_Select_MainSelect(string code,int currentPage, int pageSize)
        {
            var query = myDbContext.inv_trf.Where(e => e.Del_flag == '0' && e.trf_audit_status == "1" && e.trf_ckpd== '1' && e.trf_rkpd == '0');
            if (!string.IsNullOrEmpty(code)) { 
            
            query=query.Where(x => x.Trf_code==code);
            }

            return query.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
                
        }
        /// <summary>
        /// 其他入库单查询总条数
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> Inv_Select_MainSelect_Count(string code)
        {
            var query = myDbContext.inv_trf.Where(x => x.Del_flag == '0' && x.trf_audit_status == "1" && x.trf_rkpd == '0');
            if (!string.IsNullOrEmpty(code))
            {

                query = query.Where(x => x.Trf_code == code);
            }

            return query.CountAsync();
        }
        /// <summary>
        /// 回调库存调拨单的数量--其他入库单审核入库之后,减少调拨单的数量
        /// </summary>
        /// <param name="Inv_trfproddtl"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        //public async Task<int> Inv_Trf_update_numderl(List<Inv_trfproddtl> Inv_trfproddtl)
        //{
        //    if (Inv_trfproddtl == null || Inv_trfproddtl.Count == 0) {

        //        return 0;
        //    }

        //    int count = 0;


        //    using (var transaction = await myDbContext.Database.BeginTransactionAsync())
        //    {
        //        try {
        //            foreach (var item in Inv_trfproddtl) {
        //                var qurey =await myDbContext.inv_trfproddtl.FirstOrDefaultAsync(s => s.Pro_code == item.Pro_code && s.stock_entry_no == item.stock_entry_no);
                    

        //                qurey.Inventory_numder -= item.Inventory_numder;


        //                if (qurey == null)
        //                {
        //                    throw new Exception("库存调拨单明细不存在");
        //                }

        //                // 标记为已修改
        //                myDbContext.inv_trfproddtl.Update(qurey);
        //            }
        //            // 保存更改
        //            count = await myDbContext.SaveChangesAsync();

        //            // 提交事务
        //            await transaction.CommitAsync();
        //        }
        //        catch (Exception ex) {
                
        //        Console.WriteLine(ex.Message);
        //        }


        //    }
        //    return count;

        //}
        /// <summary>
        ///查询调拨单--其他出库单
        /// </summary>
        /// <param name="code"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Inv_trf> Inv_Select_othoutordSelect(string code, int currentPage, int pageSize)
        {
            var query = myDbContext.inv_trf.Where(e => e.Del_flag == '0' && e.trf_audit_status == "1" && e.trf_ckpd=='0');
                if (!string.IsNullOrEmpty(code))
            {

                query = query.Where(x => x.Trf_code == code);
            }

            return query.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
        }
        /// <summary>
        /// 查询调拨单总数--其他出库单
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> Inv_Select_othoutordSelect_Count(string code)
        {
            var query = myDbContext.inv_trf.Where(x => x.Del_flag == '0' && x.trf_audit_status == "1" && x.trf_ckpd != '1');
            if (!string.IsNullOrEmpty(code))
            {

                query = query.Where(x => x.Trf_code == code);
            }

            return query.CountAsync();
        }

        /// <summary>
        /// 根据其他出库单查询的Id,查询出来关联单号,去修改调拨单的字段状态
        /// </summary>
        /// <param name="othoutord_id"></param>
        /// <returns></returns>
       
        public async Task<int> Inv_Trf_update_trf_ckpd(int othoutord_id)
        {
            // 根据其他出库单ID查询关联单号
            var othoutord = await myDbContext.inv_othoutord
                .FirstOrDefaultAsync(o => o.Othoutord_id == othoutord_id);

            if (othoutord == null)
            {
                throw new Exception($"未找到ID为{othoutord_id}的其他出库单");
            }

            var associatedCode = othoutord.othoutord_code_Associated;

            // 根据关联单号更新调拨单的trf_ckpd1字段状态
            var invTrf = await myDbContext.inv_trf
                .FirstOrDefaultAsync(t => t.Trf_code == associatedCode);

            if (invTrf == null)
            {
                throw new Exception($"未找到关联单号为{associatedCode}的调拨单");
            }

            // 修改trf_ckpd1字段状态，这里假设状态为'1'表示已出库
            invTrf.trf_ckpd = '1';

            // 保存更改
            return await myDbContext.SaveChangesAsync();

        }

        /// <summary>
        /// 入库完善审核后,修改调拨单的待入库数量
        /// </summary>
        /// <param name="inv_Othwrproddtls"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Trf_update_Pending_numder(List<Inv_Trf_update_Pending_numderUpdateDto> inv_Othwrproddtls)
        {
            using (var transaction = myDbContext.Database.BeginTransaction())
            {
                try
                {
                    // 第一步：更新调拨单明细的待入库数量
                    foreach (var item in inv_Othwrproddtls)
                    {
                        // 查找匹配的调拨单明细记录
                        var detail = await myDbContext.inv_trfproddtl
                            .Where(d => d.Pro_code == item.Pro_code &&
                                        d.stock_entry_no == item.stock_entry_no &&
                                        d.Trf_id == item.Trf_id
                                        )
                            .FirstOrDefaultAsync();

                        if (detail == null)
                        {
                            throw new Exception($"调拨单明细记录不存在：产品 {item.Pro_code}，关联单号 {item.stock_entry_no}");
                        }

                        // 检查待入库数量是否足够
                        if (detail.Pending_numder < item.Othwrproddtl_numder)
                        {
                            throw new Exception($"待入库数量不足：产品 {item.Pro_code}，当前待入库 {detail.Pending_numder}，需要减少 {item.Othwrproddtl_numder}");
                        }

                        // 减少待入库数量
                        detail.Pending_numder -= item.Othwrproddtl_numder;

                        // 更新记录
                        myDbContext.inv_trfproddtl.Update(detail);
                    }

                    // 保存所有明细更新
                    await myDbContext.SaveChangesAsync();

                    // 第二步：检查并更新调拨单主表状态
                    // 获取所有涉及的调拨单ID
                    var trfIds = await myDbContext.inv_trfproddtl
                        .Where(d => inv_Othwrproddtls.Select(i => i.stock_entry_no).Contains(d.stock_entry_no))
                        .Select(d => d.Trf_id)
                        .Distinct()
                        .ToListAsync();

                    foreach (var trfId in trfIds)
                    {
                        // 检查该调拨单是否所有明细都已入库
                        var allCompleted = await myDbContext.inv_trfproddtl
                            .Where(d => d.Trf_id == trfId)
                            .AllAsync(d => d.Pending_numder == 0);

                        if (allCompleted)
                        {
                            // 更新调拨单主表状态
                            var main = await myDbContext.inv_trf
                                .Where(m => m.Trf_id == trfId)
                                .FirstOrDefaultAsync();

                            if (main != null)
                            {
                                main.trf_rkpd = '1'; // 标记为全部入库
                                myDbContext.inv_trf.Update(main);
                            }
                        }
                    }

                    // 保存主表更新
                    int result = await myDbContext.SaveChangesAsync();
                    transaction.Commit();
                    return result;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    // 记录日志
                   
                    throw; // 重新抛出异常
                }
            }
        }
    }
}
